package cn.shujuhai.qtadmin.platform.controller;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

import org.jetbrains.annotations.NotNull;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.github.pagehelper.PageInfo;
import com.github.pagehelper.page.PageMethod;

import cn.hutool.core.text.CharSequenceUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.shujuhai.qtadmin.platform.domain.PermissionMenu;
import cn.shujuhai.qtadmin.platform.domain.SysMenu;
import cn.shujuhai.qtadmin.platform.pluging.logging.BusinessType;
import cn.shujuhai.qtadmin.platform.pluging.logging.Logging;
import cn.shujuhai.qtadmin.platform.pluging.result.Result;
import cn.shujuhai.qtadmin.platform.service.SysMenuService;

/**
 * 用户API
 *
 * @author dch798
 * @date 2021/08/21 22:13
 **/
@RestController
@RequestMapping("admin/menu")
public class AdminMenuController {

    public static final String HREF = "href";

    final SysMenuService sysMenuService;

    public AdminMenuController(SysMenuService sysMenuService) {
        this.sysMenuService = sysMenuService;
    }

    /**
     *
     * @param page
     *            当前页
     * @return 角色列表
     */
    @PostMapping("menuList")
    @Logging(title = "菜单列表", describe = "菜单列表", type = BusinessType.QUERY)
    public Result menuList(Integer page, Integer limit, @NotNull SysMenu sysMenu) {
        PageMethod.startPage(page == 0 ? 1 : page, limit == 0 ? 15 : limit);
        var queryWrapper = new QueryWrapper<SysMenu>();
        if (CharSequenceUtil.isNotBlank(sysMenu.getTitle())) {
            queryWrapper.like("title", sysMenu.getTitle());
        }
        if (CharSequenceUtil.isNotBlank(sysMenu.getHref())) {
            queryWrapper.like(HREF, sysMenu.getHref());
        }
        var menuList = sysMenu.selectList(queryWrapper);
        return Result.success("获取成功", new PageInfo<>(menuList));
    }

    /**
     *
     * @param permissionId
     *            权限Id
     * @return 权限列表
     */
    @PostMapping("menus")
    @Logging(title = "菜单树", describe = "菜单树", type = BusinessType.QUERY)
    public Result menus(Integer permissionId) {
        var menus = new SysMenu().selectAll();
        var checkedIds =
            new PermissionMenu().selectList(new QueryWrapper<PermissionMenu>().eq("permission_id", permissionId));
        var checkedId = checkedIds.stream().map(PermissionMenu::getMenuId).distinct().toArray(Long[]::new);
        var map = new HashMap<String, Object>(2);
        map.put("menus", menus);
        map.put("checkedId", checkedId);
        return Result.success("获取成功", map);
    }

    /**
     *
     * @param sysMenu
     *            菜单信息
     * @return 新增菜单结果
     */
    @PostMapping("menuAdd")
    @Logging(title = "新增菜单", describe = "新增菜单", type = BusinessType.ADD)
    public Result menuAdd(@NotNull SysMenu sysMenu) {
        if (sysMenu.selectCount(new QueryWrapper<SysMenu>().eq(HREF, CharSequenceUtil.trim(sysMenu.getHref()))) > 0) {
            return Result.failure("该菜单已经存在");
        }
        sysMenu.insert();
        return Result.success("新增成功");
    }

    /**
     *
     * @param sysMenu
     *            菜单信息
     * @return 修改菜单结果
     */
    @PostMapping("menuUpdate")
    @Logging(title = "修改菜单", describe = "修改菜单", type = BusinessType.EDIT)
    public Result menuUpdate(@NotNull SysMenu sysMenu) {
        if (sysMenu.updateById()) {
            return Result.success("修改成功");
        }
        return Result.failure("修改失败");
    }

    /**
     *
     * @param id
     *            id
     * @return result
     */
    @PostMapping("menuDelete")
    @Transactional(rollbackFor = Exception.class)
    @Logging(title = "菜单删除", describe = "菜单删除", type = BusinessType.REMOVE)
    public Result menuDelete(Long id) {
        var ids = new ArrayList<Long>();
        var menu = new SysMenu();
        var permissionMenu = new PermissionMenu();
        var allMenus = menu.selectAll();
        ids.add(id);
        this.getChildrenPermissions(id, allMenus, ids);
        menu.delete(new QueryWrapper<SysMenu>().in("id", ids));
        permissionMenu.delete(new QueryWrapper<PermissionMenu>().in("menu_id", ids));
        return Result.success("删除成功");
    }

    /**
     *
     * @param id
     *            id
     * @param allMenus
     *            allMenus
     * @param ids
     *            ids
     */
    private void getChildrenPermissions(Long id, @NotNull List<SysMenu> allMenus, List<Long> ids) {
        var childrens = allMenus.stream().filter(s -> s.getParentId().equals(id)).collect(Collectors.toList());
        if (ObjectUtil.isNotEmpty(childrens)) {
            childrens.forEach(x -> {
                ids.add(x.getId());
                this.getChildrenPermissions(x.getId(), allMenus, ids);
            });
        }
    }

    /**
     * 用户菜单列表
     * 
     * @return 用户菜单列表
     */
    @GetMapping("userMenus")
    @Logging(title = "用户菜单", describe = "用户菜单", type = BusinessType.REMOVE)
    public Map<String, Object> userMenus() {
        return this.sysMenuService.getMenus4user();
    }
}
